﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.Model;
using VAdvantage.Classes;
using VAdvantage.Utility;
using System.Threading;
using System.Text;
using System.Windows.Controls.Primitives;
using VAdvantage.Apps;
using System.Data.SqlClient;
using VAdvantage.DataBase;
using System.Data;
using System.Windows.Printing;
using VAdvantage.Grids;
using VAdvantage.Framework;
using VAdvantage.Logging;

namespace VAdvantage.Print
{
    public partial class Viewer : Apps.CFrame
    {

        /** Window No */
        private int m_WindowNo;
        /** Print Context */
        private Ctx m_ctx;
        /** Page No */
        private int m_pageNo = 1;
        /** Max Page Number */
        private int m_pageMax = 1;
        /** View Pane */
        private View m_viewPanel;
        /** Setting Values */
        private bool m_setting = false;
        /** Report Engine */
        private ReportEngine m_reportEngine;
        /** Drill Down/Across */
        private bool m_drillDown = true;
        /** Table ID */
        private int m_AD_Table_ID = 0;
        private bool m_isCanExport;

        public Viewer(ReportEngine re)
            : base(Msg.GetMsg(Envs.GetContext(), "ReportViewer", true))
        {
            ThreadPool.QueueUserWorkItem(delegate
            {
                m_WindowNo = Envs.CreateWindowNo(this);
                m_reportEngine = re;
                m_AD_Table_ID = re.GetPrintFormat().GetAD_Table_ID();

                if (!MRole.GetDefault().IsCanReport(m_AD_Table_ID))
                {
                    ShowMessage.Error("AccessCannotReport", false);
                    this.Close();
                    //close the window
                }

                m_isCanExport = MRole.GetDefault().IsCanExport(m_AD_Table_ID);


                try
                {
                    m_viewPanel = re.GetView();
                    m_ctx = m_reportEngine.GetCtx();
                    //done

                    KeyNamePair[] keys = FillComboReport(m_reportEngine.GetPrintFormat().Get_ID());

                    bool pass = false;
                    Dispatcher.BeginInvoke(delegate
                    {
                        InitializeComponent();
                        JbInit();
                        comboReport.Items.Clear();

                        for (int i = 0; i <= keys.Length - 1; i++)
                        {
                            comboReport.Items.Add(keys[i]);
                            if (selectValue == keys[i])
                                comboReport.SelectedItem = keys[i];
                        }

                        Utility.Envs.RegisterWindowForm(this);
                        this.Show();
                        pass = true;

                    });

                    while (!pass)
                        Thread.Sleep(1);

                    FillComboReport(m_reportEngine.GetPrintFormat().Get_ID());
                }
                catch
                {
                }
            });

        }

        private void JbInit()
        {
            //ScrollHelper.RegisterForNotification("HorizontalOffset", reportViewer1, OnHorizontalOffsetChanged);
            ScrollHelper.RegisterForNotification("VerticalOffset", reportViewer1, OnVerticalOffsetChanged);

            m_viewPanel.Margin = new Thickness(0, 0, 0, 0);
            m_pageMax = m_viewPanel.GetPageCount();
            txtPage.Text = "1";
            //m_viewPanel.Background = new SolidColorBrush(Colors.DarkGray);
            reportViewer1.Content = m_viewPanel;
        }

        public void OnVerticalOffsetChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ScrollEvent();
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            //this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            //this.DialogResult = false;
        }

        private void reportViewer1_LayoutUpdated(object sender, EventArgs e)
        {
            //m_viewPanel.Paint();
        }

        private void reportViewer1_Loaded(object sender, RoutedEventArgs e)
        {
            //SetTitle(Msg.GetMsg(m_ctx, "Report") + ": " + m_reportEngine.GetName() + "  " + Envs.GetHeader(Envs.GetCtx(), 0));
            //StringBuilder sb = new StringBuilder();
            //sb.Append(m_viewPanel.GetPaper().ToString(m_ctx))
            //    .Append(" - ").Append(Msg.GetMsg(m_ctx, "DataCols")).Append("=")
            //    .Append(m_reportEngine.GetColumnCount())
            //    .Append(", ").Append(Msg.GetMsg(m_ctx, "DataRows")).Append("=")
            //    .Append(m_reportEngine.GetRowCount());
            //reportStatus.SetStatusLine(sb.ToString());
            Revalidate();
            m_viewPanel.Paint(this);
        }

        private void bPrev_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {

        }

        private void bPrev_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            SetPage(m_pageNo - 1);
        }

        private void bNext_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            SetPage(m_pageNo + 1);
        }

        private void SetPage(int page)
        {
            m_setting = true;

            SetPageIndicator(page);
            //
            Rectangle pageRectangle = m_viewPanel.GetRectangleOfPage(m_pageNo);
            double left = pageRectangle.Margin.Left;
            double top = pageRectangle.Margin.Top;
            pageRectangle.Margin = new Thickness(left -= View.MARGIN, top -= View.MARGIN, 0, 0);
            reportViewer1.ScrollToVerticalOffset(pageRectangle.Margin.Top);

            m_setting = false;
        }	// setPage

        private void SetPageIndicator(int page)
        {
            m_pageNo = page;
            if (m_pageNo < 1)
                m_pageNo = 1;
            if (page > m_pageMax)
                m_pageNo = m_pageMax;
            
            //bPrev.isEnabled = m_pageNo != 1;
            //bNext.Enabled = m_pageNo != m_pageMax;

            // Set Page
            txtPage.Text = m_pageNo.ToString();
            reportStatus.SetPageLine(m_pageNo.ToString(), m_pageMax.ToString());
        }


        #region Data Members for Implementing using Control Template

        #endregion

        void ScrollEvent()
        {
            Point p = new Point(reportViewer1.HorizontalOffset, reportViewer1.VerticalOffset);
            int newPage = (int)Math.Round((double)m_viewPanel.GetPageNoAt(p));
            SetPageIndicator(newPage);
        }

        private void bPrint_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {

        }

        private void bPrint_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            m_viewPanel.Print();
        }

        KeyNamePair selectValue = null;
        private KeyNamePair[] FillComboReport(int AD_PrintFormat_ID)
        {
            List<KeyNamePair> list = new List<KeyNamePair>();
            //	fill Report Options
            SqlParameter[] param = new SqlParameter[1];
            String sql = MRole.GetDefault().AddAccessSQL(
                "SELECT AD_PrintFormat_ID, Name, Description "
                    + "FROM AD_PrintFormat "
                    + "WHERE AD_Table_ID=@tableid "
                    + "ORDER BY Name",
                "AD_PrintFormat", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
            int AD_Table_ID = m_reportEngine.GetPrintFormat().GetAD_Table_ID();
            param[0] = new SqlParameter("@tableid", AD_Table_ID.ToString());
            try
            {
                IDataReader dr = DB.ExecuteReader(sql, param, null);
                while (dr.Read())
                {
                    KeyNamePair pp = new KeyNamePair(Util.GetValueOfInt(dr[0].ToString()), dr[1].ToString());
                    list.Add(pp);
                    if (Util.GetValueOfInt(dr[0].ToString()) == AD_PrintFormat_ID)
                        selectValue = pp;
                }
                dr.Close();
            }
            catch (Exception e)
            {
               // log.Log(Level.SEVERE, sql, e);
            }
            StringBuilder sb = new StringBuilder("** ").Append(Msg.GetMsg(m_ctx, "NewReport")).Append(" **");
            KeyNamePair pp_ = new KeyNamePair(-1, sb.ToString());
            list.Add(pp_);

            return list.ToArray();
            //comboReport.Items.Add(pp_);
            //if (selectValue != null)
            //    comboReport.SelectedItem = selectValue;
        }

        private void ChildWindow_Closed(object sender, EventArgs e)
        {

        }

        private void bExit_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {

        }

        private void bExit_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            this.Close();
        }

        private void comboReport_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //Cmd_Report();
        }	//	fillComboReport

        private void Cmd_Report(KeyNamePair pp)
        {
            
            ThreadPool.QueueUserWorkItem(delegate
            {

                if (pp == null)
                    return;
                //
                //this.Cursor = Cursors.Wait;
                MPrintFormat pf = null;
                int AD_PrintFormat_ID = pp.GetKey();

                //	create new
                if (AD_PrintFormat_ID == -1)
                {
                    int AD_ReportView_ID = m_reportEngine.GetPrintFormat().GetAD_ReportView_ID();
                    if (AD_ReportView_ID != 0)
                    {
                        String name = m_reportEngine.GetName();
                        int index = name.LastIndexOf("_");
                        if (index != -1)
                            name = name.Substring(0, index);
                        pf = MPrintFormat.CreateFromReportView(m_ctx, AD_ReportView_ID, name);
                    }
                    else
                    {
                        int AD_Table_ID = m_reportEngine.GetPrintFormat().GetAD_Table_ID();
                        pf = MPrintFormat.CreateFromTable(m_ctx, AD_Table_ID);
                    }
                    if (pf != null)
                    {
                        KeyNamePair[] keys = FillComboReport(pf.Get_ID());

                        Dispatcher.BeginInvoke(delegate
                        {
                            comboReport.Items.Clear();
                            for (int i = 0; i <= keys.Length - 1; i++)
                            {
                                comboReport.Items.Add(keys[i]);
                                if (selectValue == keys[i])
                                    comboReport.SelectedItem = keys[i];
                            }
                        });
                    }
                    else
                        return;
                }
                else
                    pf = MPrintFormat.Get(Envs.GetCtx(), AD_PrintFormat_ID, true);

                //	Get Language from previous - thanks Gunther Hoppe 
                if (m_reportEngine.GetPrintFormat() != null)
                {
                    pf.SetLanguage(m_reportEngine.GetPrintFormat().GetLanguage());		//	needs to be re-set - otherwise viewer will be blank
                    pf.SetTranslationLanguage(m_reportEngine.GetPrintFormat().GetLanguage());
                }

                m_reportEngine.SetViewer(this);
                m_reportEngine.SetPrintFormat(pf);
            });
        }


        KeyNamePair[] newFormat = null;
        private void bGo_Click(object sender, RoutedEventArgs e)
        {
            SetBusy(true);
            this.Cursor = Cursors.Wait;
            KeyNamePair pp = (KeyNamePair)comboReport.SelectedItem;
            Cmd_Report(pp);

        }	//	cmd_report

        public void SetBusy(bool isBusy)
        {
            if (isBusy)
            {
                this.Cursor = Cursors.Wait;
                busyIndicator1.IsBusy = true;
            }
            else
            {
                this.Cursor = Cursors.Arrow;
                busyIndicator1.IsBusy = false;
            }
        }

        private void CFrame_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void busyIndicator1_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void bFind_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Cmd_Find();
        }

        private void Cmd_Find()
        {
            this.Cursor = Cursors.Wait;
            ThreadPool.QueueUserWorkItem(delegate
            {
                
                int AD_Table_ID = m_reportEngine.GetPrintFormat().GetAD_Table_ID();

                String title = null;
                String tableName = null;

                // Get Find Tab Info
                String sql = "SELECT t.AD_Tab_ID "
                    // ,w.Name, t.Name, w.IsDefault, t.SeqNo, ABS
                    // (tt.AD_Window_ID-t.AD_Window_ID)
                    + "FROM AD_Tab t"
                    + " INNER JOIN AD_Window w ON (t.AD_Window_ID=w.AD_Window_ID)"
                    + " INNER JOIN AD_Table tt ON (t.AD_Table_ID=tt.AD_Table_ID) "
                    // jz + "WHERE AD_Table_ID=@param1 "
                    + "WHERE tt.AD_Table_ID=@param1 "
                    + "ORDER BY w.IsDefault DESC, t.SeqNo, ABS (tt.AD_Window_ID-t.AD_Window_ID)";
                int AD_Tab_ID = DB.GetSQLValue(null, sql, AD_Table_ID);
                //
                sql = "SELECT Name, TableName FROM AD_Tab_v WHERE AD_Tab_ID=@param1";
                if (!Envs.IsBaseLanguage(Envs.GetCtx(), "AD_Tab"))
                    sql = "SELECT Name, TableName FROM AD_Tab_vt WHERE AD_Tab_ID=@param1"
                        + " AND AD_Language='" + Envs.GetAD_Language(Envs.GetCtx()) + "'";
                try
                {
                    SqlParameter[] param = new SqlParameter[1];
                    param[0] = new SqlParameter("@param1", AD_Tab_ID);
                    IDataReader dr = DB.ExecuteReader(sql, param, null);
                    while (dr.Read())
                    {
                        title = dr[0].ToString();
                        tableName = dr[1].ToString();
                    }
                    //
                    dr.Close();
                }
                catch (Exception e)
                {
                    //log.Log(Level.SEVERE, sql, e);
                }

                GridField[] findFields = null;
                if (tableName != null)
                    findFields = GridField.CreateFields(m_ctx, m_WindowNo, 0, AD_Tab_ID, 0);

                if (findFields == null)		// No Tab for Table exists
                {
                    Dispatcher.BeginInvoke(() => this.Cursor = Cursors.Arrow);
                }
                else
                {
                    Dispatcher.BeginInvoke(delegate
                   {
                       Find find = new Find(m_WindowNo, title, 0, AD_Table_ID, tableName, "", findFields, 1, false);
                       find.Closed += new EventHandler(find_Closed);
                       find.Show();
                       //m_reportEngine.SetQuery(find.GetQuery());
                       //find = null;
                   });
                }
            });
            //m_viewPanel.Refresh();
            //m_viewPanel.RefreshMe();
            //Cmd_Drill();	// setCursor
        }

        void find_Closed(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(delegate
            {
                Find find = (sender as Find);
                m_reportEngine.SetQuery(find.GetQuery());
                Dispatcher.BeginInvoke(() => m_viewPanel.Paint(this));
                Dispatcher.BeginInvoke(() => Revalidate());
                Dispatcher.BeginInvoke(() => this.Cursor = Cursors.Arrow);
            });
        }


        private void Revalidate()
        {
            m_pageMax = m_viewPanel.GetPageCount();
            reportViewer1.ScrollToVerticalOffset(0);
            // Report Info
            SetTitle(Msg.GetMsg(m_ctx, "Report") + ": " + m_reportEngine.GetName() + "  " + Envs.GetHeader(Envs.GetCtx(), 0));
            StringBuilder sb = new StringBuilder();
            sb.Append(m_viewPanel.GetPaper().ToString(m_ctx))
                .Append(" - ").Append(Msg.GetMsg(m_ctx, "DataCols")).Append("=")
                .Append(m_reportEngine.GetColumnCount())
                .Append(", ").Append(Msg.GetMsg(m_ctx, "DataRows")).Append("=")
                .Append(m_reportEngine.GetRowCount());
            reportStatus.SetStatusLine(sb.ToString());
            
            //
            m_setting = true;

            SetPageIndicator(m_pageNo);
            //
            Rectangle pageRectangle = m_viewPanel.GetRectangleOfPage(m_pageNo);
            pageRectangle.Margin = new Thickness(pageRectangle.Margin.Left - View.MARGIN, pageRectangle.Margin.Top - View.MARGIN, 0, 0);

            txtPage.Text = "1";
            //SetPage(m_pageNo);
        }	// revalidate

    }
}

